package win.demonlegion.eshimin.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import win.demonlegion.eshimin.config.EshiminConfig;
import win.demonlegion.eshimin.request.BaseRequest;
import win.demonlegion.eshimin.request.AccessTokenRequest;
import win.demonlegion.eshimin.response.AccessTokenResponse;
import win.demonlegion.eshimin.response.UserBasicResponse;
import win.demonlegion.eshimin.response.UserIdentityResponse;
import win.demonlegion.eshimin.response.UserInfoThirdResponse;
import win.demonlegion.util.*;

@Service
@Slf4j
public class EshiminService {
    @Autowired
    private EshiminConfig eshiminConfig;
    @Autowired
    private RestTemplate restTemplate;

    public AccessTokenResponse getAccessToken(String code) {
        AccessTokenRequest request = new AccessTokenRequest();
        request.setClient_id(eshiminConfig.getAppKey());
        request.setClient_secret(eshiminConfig.getAppSecret());
        request.setRedirect_uri(eshiminConfig.getRedirectUri());
        request.setCode(code);
        String requestUrl = RequestUtil.getUrl(eshiminConfig.getAccessTokenUrl(), request, false);
        String response = restTemplate.getForObject(requestUrl, String.class);
        log.info(response);
        return JSON.parseObject(response, AccessTokenResponse.class);
    }

    public UserBasicResponse userBasic(String userName, String accessToken) {
        BaseRequest request = new BaseRequest();
        request.setAccess_token(accessToken);
        String response = restTemplate.getForObject(RequestUtil.getUrl(eshiminConfig.getUserBasicUrl() + userName, request), String.class);
        log.info(response);
        return JSON.parseObject(response, UserBasicResponse.class);
    }

    public UserIdentityResponse userIdentity(String userName, String accessToken) {
        BaseRequest request = new BaseRequest();
        request.setAccess_token(accessToken);
        String response = restTemplate.getForObject(RequestUtil.getUrl(eshiminConfig.getUserIdentityUrl() + userName, request), String.class);
        log.info(response);
        return JSON.parseObject(response, UserIdentityResponse.class);
    }

    public UserInfoThirdResponse userInfoThird(String accessToken) {
        JSONObject body = new JSONObject();
        body.put("access_token", accessToken);
        String encryptBody = AesUtils.encrypt(body.toJSONString(), eshiminConfig.getAesKey(), eshiminConfig.getAesIv());
        HttpHeaders headers = new HttpHeaders();
        headers.set("client-id", eshiminConfig.getClientId());
        headers.set("api-id", eshiminConfig.getApiId());
        String aesKey = RsaUtils.encryptByPublicKey(eshiminConfig.getProcPublicKey(), eshiminConfig.getAesKey());
        headers.set("aes-key", aesKey);
        String aesIv = RsaUtils.encryptByPublicKey(eshiminConfig.getProcPublicKey(), eshiminConfig.getAesIv());
        headers.set("aes-iv", aesIv);
        log.info("aes-key: {}, aes-iv: {}", aesKey, aesIv);
        long timestamp = System.currentTimeMillis();
        String sign = generateSign(timestamp);
        headers.set("sign", sign);
        headers.set("timestamp", timestamp+"");
        HttpEntity<String> entity = new HttpEntity<>(encryptBody, headers);
        log.info("headers: {}", JSON.toJSONString(headers));
        ResponseEntity<String> response = restTemplate.postForEntity(eshiminConfig.getProcGatewayUrl(), entity, String.class);
        if (response.getStatusCodeValue() == 200) {
            // 请求成功，解密数据并转换
            log.info(response.getBody());
            JSONObject jsonObject = JSON.parseObject(response.getBody());
            if (jsonObject.getIntValue("status") == 200) {
                String decryptResponse = AesUtils.decrypt(jsonObject.getString("data"), eshiminConfig.getAesKey(), eshiminConfig.getAesIv());
                return JSON.parseObject(decryptResponse, UserInfoThirdResponse.class);
            }
        }
        return null;
    }

    public String generateSign(long timestamp) {
        String md5Content = eshiminConfig.getClientId() + timestamp + eshiminConfig.getClientSecret();
        return MD5Util.MD5(md5Content);
    }
}
